<?php

$filename = basename($_REQUEST['file']);
$fromfolder = $_REQUEST["folder"];
$dir_root = dirname(__FILE__);
$fromfolder = $dir_root . "/" . $fromfolder;
$local_file = $fromfolder . '/' . $filename;

// set the download rate limit (=> 0,5 kb/s)
$download_rate = 200.5;

class RatedSender {

    /**
     * Send a file as download to the browser (maybe limited in speed)
     *
     * @param string $filePath
     * @param int $rate speedlimit in KB/s
     * @return void
     */
    public  function send($filePath, $rate = 0)
    {
        // Check if file exists
        if (!is_file($filePath))
        {
            throw new Exception('File not found.');
        }

        // get more information about the file
        $filename = basename($filePath);
        $size = filesize($filePath);
        $finfo = finfo_open(FILEINFO_MIME);
        $mimetype = finfo_file($finfo, realpath($filePath));
        finfo_close($finfo);

        // Create file handle
        $fp = fopen($filePath, 'rb');

        $seekStart = 0;
        $seekEnd = $size;

        // Check if only a specific part should be sent
        if (isset($_SERVER['HTTP_RANGE']))
        {
            // If so, calculate the range to use
            $range = explode('-', substr($_SERVER['HTTP_RANGE'], 6));

            $seekStart = intval($range[0]);
            if ($range[1] > 0)
            {
                $seekEnd = intval($range[1]);
            }

            // Seek to the start
            fseek($fp, $seekStart);

            // Set headers incl range info
            header('HTTP/1.1 206 Partial Content');
            header(sprintf('Content-Range: bytes %d-%d/%d', $seekStart, $seekEnd, $size));
        }
        else
        {
            // Set headers for full file
            header('HTTP/1.1 200 OK');
        }

        // Output some headers
        header('Cache-Control: private');
        header('Content-Type: ' . $mimetype);
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Content-Transfer-Encoding: binary');
        header("Content-Description: File Transfer");
        header('Content-Length: ' . ($seekEnd - $seekStart));
        header('Accept-Ranges: bytes');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($filePath)) . ' GMT');

        $block = 1024;
        // limit download speed
        if ($rate > 0)
        {
            $block *= $rate;
        }

        // disable timeout before download starts
        set_time_limit(0);

        // Send file until end is reached
        while (!feof($fp)) {
            $timeStart = microtime(true);
            echo fread($fp, $block);
            flush();
            $wait = (microtime(true) - $timeStart) * 1000000;

            // if speedlimit is defined, make sure to only send specified bytes per second
            if ($rate > 0)
            {
                usleep(1000000 - $wait);
            }
        }

        // Close handle
        fclose($fp);
    }

}

//try {
//    $ratedSender = new RatedSender();
//    $ratedSender->send($local_file, 20);
//} catch (Exception $e) {
//    header('HTTP/1.1 404 File Not Found');
//    die('Sorry, an error occured.');
//}
if (file_exists($local_file) && is_file($local_file))
{

    // send headers
    header('Cache-control: private');
    header("X-LIGHTTPD-KBytes-per-second: 50");
    header('Content-Type: application/octet-stream');
    header('Content-Length: ' . filesize($local_file));
    header('Content-Disposition: filename=' . $filename);
    // flush content
    flush();
    // open file stream
    $file = fopen($local_file, "r");
    while (!feof($file)) {
        // send the current file part to the browser
        print fread($file, round($download_rate * 1024));
        // flush the content to the browser
        flush();
        // sleep one second
        sleep(1);
    }
    // close file stream
    fclose($file);
}
else
{
    die('Error: The file ' . $local_file . ' does not exist!');
}
?>
